
module Envelope_Detector_Digital
#(
    parameter WIDTH = 10,
    parameter MAXINTERVAL = 64,
    parameter MAXINTERVAL_WIDTH = 8
)
(
    input wire signed [WIDTH-1:0] i_SignalInput,
    input wire [MAXINTERVAL_WIDTH-1:0] i_Interval,
    input wire i_clk,
    input wire i_rst,
    output reg signed [WIDTH-1:0] o_Envelope
);

//Generate Shift Register
wire signed [WIDTH-1:0] Shift_Reg [MAXINTERVAL-1:0];
genvar i;
generate
for( i=0 ; i<MAXINTERVAL ; i=i+1 )begin: shreg_first_stage
    if(i==0)begin: fir_first_input_reg_del
        Shift_Reg_ED
        #(  
            .WIDTH    (WIDTH)
        )ed_shift_reg(
            .i_clk    (i_clk),
            .i_rst    (i_rst),
            .i_regin     (i_SignalInput),
            .o_regout    (Shift_Reg[i])
        );
    end
    else begin: shreg_mid_stage
        Shift_Reg_ED   
        #(  
            .WIDTH    (WIDTH)
        )ed_shift_reg(
            .i_clk (i_clk),
            .i_rst (i_rst),
            .i_regin  (Shift_Reg[i-1]),
            .o_regout (Shift_Reg[i])
        );
    end
end
endgenerate

//Differentiator
wire signed [WIDTH-1:0] diff;
reg signed [WIDTH-1:0] diff_pre;
assign diff=i_SignalInput-Shift_Reg[i_Interval-1];
//Store Previous Diff
always@(posedge i_clk or posedge i_rst) begin
    if(i_rst) begin
        diff_pre<='b0;
    end
    else begin
        diff_pre<=diff;
    end
end

//Find Envelope
wire Diff_Sign;
assign Diff_Sign=diff_pre[WIDTH-1]^diff[WIDTH-1];
always@(posedge i_clk or posedge i_rst) begin
    if(i_rst) begin
        o_Envelope<='b0;
    end
    else begin
        if((Diff_Sign&(i_SignalInput[WIDTH-1]==0))) begin
            o_Envelope<=i_SignalInput;
        end
        else begin
            o_Envelope<=o_Envelope;
        end
    end
end



endmodule


module Shift_Reg_ED
#(
    parameter WIDTH = 10
)
(
    input wire [WIDTH-1:0] i_regin,
    input wire i_clk,
    input wire i_rst,
    output reg [WIDTH-1:0] o_regout
);

always@(posedge i_clk or posedge i_rst) begin
    if(i_rst) begin
        o_regout<='b0;
    end
    else begin
        o_regout<=i_regin;
    end
end

endmodule